﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using System.Windows.Media.Media3D;

namespace _3D_Introduction
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        double angle_flat = Math.PI * 3 / 2;
        double angle_up = 0;
        double distance = 20;

        public MainWindow()
        {
            InitializeComponent();

            Viewbox viewbox = new Viewbox();
            Content = viewbox;

            Viewport3D viewport3D = new Viewport3D();
            viewbox.Child = viewport3D;

            viewport3D.Height = 300;
            viewport3D.Width = 600;

            PerspectiveCamera camera = new PerspectiveCamera();
            camera.Position = new Point3D(0, 0, distance);
            camera.LookDirection = new Vector3D(0, 0, -distance);
            camera.UpDirection = new Vector3D(0, 1, 0);
            camera.FieldOfView = 50;

            viewport3D.Camera = camera;

            #region meinErstesDreieck
            {
                ModelVisual3D modelVisual3DMesh = new ModelVisual3D();
                viewport3D.Children.Add(modelVisual3DMesh);

                GeometryModel3D mesh = new GeometryModel3D();
                modelVisual3DMesh.Content = mesh;

                MeshGeometry3D meshGeometry3D = new MeshGeometry3D();
                mesh.Geometry = meshGeometry3D;

                // Form the mesh (DRAW Counter-Clockwise!!)
                meshGeometry3D.Positions.Add(new Point3D(0, 0, 0));
                meshGeometry3D.Positions.Add(new Point3D(2, 0, 0));
                meshGeometry3D.Positions.Add(new Point3D(0, 3, 0));

                meshGeometry3D.Positions.Add(new Point3D(2, 3, 0));
                meshGeometry3D.Positions.Add(new Point3D(0, 3, 0));
                meshGeometry3D.Positions.Add(new Point3D(2, 0, 0));


                // Give the Triangle-Points some indices
                meshGeometry3D.TriangleIndices.Add(0);
                meshGeometry3D.TriangleIndices.Add(1);
                meshGeometry3D.TriangleIndices.Add(2);

                meshGeometry3D.TriangleIndices.Add(3);
                meshGeometry3D.TriangleIndices.Add(4);
                meshGeometry3D.TriangleIndices.Add(5);

                // Set Normals to +z, the start camera position (Normals are for lighting)
                meshGeometry3D.Normals.Add(new Vector3D(0, 0, 1));
                meshGeometry3D.Normals.Add(new Vector3D(0, 0, 1));
                meshGeometry3D.Normals.Add(new Vector3D(0, 0, 1));

                meshGeometry3D.Normals.Add(new Vector3D(0, 0, -1));
                meshGeometry3D.Normals.Add(new Vector3D(0, 0, -1));
                meshGeometry3D.Normals.Add(new Vector3D(0, 0, -1));

                //meshGeometry3D.Positions.Add(new Point3D(-0.5, -0.5, -0.5));
                //meshGeometry3D.Positions.Add(new Point3D(-0.5, 0.5, -0.5));
                //meshGeometry3D.Positions.Add(new Point3D(0.5, 0.5, -0.5));
                //meshGeometry3D.Positions.Add(new Point3D(0.5, 0.5, -0.5));
                //meshGeometry3D.Positions.Add(new Point3D(0.5, -0.5, -0.5));
                //meshGeometry3D.Positions.Add(new Point3D(-0.5, -0.5, -0.5));


                //meshGeometry3D.TriangleIndices.Add(0);
                //meshGeometry3D.TriangleIndices.Add(1);
                //meshGeometry3D.TriangleIndices.Add(2);
                //meshGeometry3D.TriangleIndices.Add(3);
                //meshGeometry3D.TriangleIndices.Add(4);
                //meshGeometry3D.TriangleIndices.Add(5);

                //meshGeometry3D.Normals.Add(new Vector3D(0, 0, -1));
                //meshGeometry3D.Normals.Add(new Vector3D(0, 0, -1));
                //meshGeometry3D.Normals.Add(new Vector3D(0, 0, -1));
                //meshGeometry3D.Normals.Add(new Vector3D(0, 0, -1));
                //meshGeometry3D.Normals.Add(new Vector3D(0, 0, -1));
                //meshGeometry3D.Normals.Add(new Vector3D(0, 0, -1));


                mesh.Material = new DiffuseMaterial(Brushes.DarkCyan);
                mesh.BackMaterial = new DiffuseMaterial(Brushes.Red);


            }
            #endregion 

            #region light setup
            {
                ModelVisual3D lightModelVisual3D = new ModelVisual3D();
                viewport3D.Children.Add(lightModelVisual3D);

                Model3DGroup lightSources = new Model3DGroup();
                lightModelVisual3D.Content = lightSources;

                lightSources.Children.Add(new DirectionalLight(Colors.White, new Vector3D(-1, -2, 1)));
                lightSources.Children.Add(new AmbientLight(Colors.LightGray));
            }
            #endregion

            KeyDown += (s, a) =>
            {
                #region flach
                if (Keyboard.IsKeyDown(Key.Left))
                {
                    angle_flat += Math.PI / 36;

                    camera.Position = new Point3D(
                        distance * Math.Cos(angle_flat),
                        camera.Position.Y,
                        -distance * Math.Sin(angle_flat));

                    camera.LookDirection = new Vector3D(
                        -camera.Position.X,
                        -camera.Position.Y,
                        -camera.Position.Z);
                }

                if (Keyboard.IsKeyDown(Key.Right))
                {
                    angle_flat -= Math.PI / 36;

                    camera.Position = new Point3D(
                        distance * Math.Cos(angle_flat),
                        camera.Position.Y,
                        -distance * Math.Sin(angle_flat));

                    camera.LookDirection = new Vector3D(
                        -camera.Position.X,
                        -camera.Position.Y,
                        -camera.Position.Z);
                }
                #endregion

                #region hoch
                if (Keyboard.IsKeyDown(Key.Up))
                {
                    angle_up += Math.PI / 36;

                    camera.Position = new Point3D(
                        camera.Position.X,
                        distance * Math.Sin(angle_up),
                        distance * Math.Cos(angle_up));

                    camera.LookDirection = new Vector3D(
                        -camera.Position.X,
                        -camera.Position.Y,
                        -camera.Position.Z);
                }

                if (Keyboard.IsKeyDown(Key.Down))
                {
                    angle_up -= Math.PI / 36;

                    camera.Position = new Point3D(
                        camera.Position.X,
                        distance * Math.Sin(angle_up),
                        distance * Math.Cos(angle_up));

                    camera.LookDirection = new Vector3D(
                        -camera.Position.X,
                        -camera.Position.Y,
                        -camera.Position.Z);
                }
                #endregion

                #region depth
                if (Keyboard.IsKeyDown(Key.W))
                {
                    distance -= 0.5;

                    double length = Math.Sqrt(
                        Math.Pow(camera.Position.X, 2)
                        + Math.Pow(camera.Position.Y, 2)
                        + Math.Pow(camera.Position.Z, 2)
                        );

                    camera.Position = new Point3D(
                        camera.Position.X / length * distance,
                        camera.Position.Y / length * distance,
                        camera.Position.Z / length * distance);

                    camera.LookDirection = new Vector3D(
                        -camera.Position.X,
                        -camera.Position.Y,
                        -camera.Position.Z);
                }

                if (Keyboard.IsKeyDown(Key.S))
                {
                    distance += 0.5;

                    double length = Math.Sqrt(
                        Math.Pow(camera.Position.X, 2)
                        + Math.Pow(camera.Position.Y, 2)
                        + Math.Pow(camera.Position.Z, 2)
                        );

                    camera.Position = new Point3D(
                        camera.Position.X / length * distance,
                        camera.Position.Y / length * distance,
                        camera.Position.Z / length * distance);

                    camera.LookDirection = new Vector3D(
                        -camera.Position.X,
                        -camera.Position.Y,
                        -camera.Position.Z);
                }
                #endregion

            };
            
        }
    }
}
